package jmodel.value;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import jf.jextn.JExtn;
import jf.jextn.xml.Xmlizable;
import jmodel.Attribute;
import jmodel.Model;

public class ModelInstance implements Xmlizable {
    private static final long serialVersionUID = 1L;

    private final Model model;

    private final Map<String, Object> state = new HashMap<String, Object>();

    private transient Map<String, Object> readonlyState;

    public ModelInstance(Model model) {
        this.model = model;
    }

    public Object set(Attribute attr, Object value) {
        validateAttribute(attr);

        Object old = null;

        if (value == null) {
            old = state.remove(attr);
        } else {
            old = state.put(attr.getName(), value);
        }

        return old;
    }

    public Object get(Attribute attr) {
        validateAttribute(attr);

        return state.get(attr.getName());
    }

    private void validateAttribute(Attribute attr) {
        JExtn.checkNull(attr, "attribute is null");
        JExtn.checkCondition((attr.getOwner() != model), "wrong attribute owner");
    }

    public void clear() {
        state.clear();
    }

    public Map<String, Object> getStateAsMap() {
        if (readonlyState == null) {
            readonlyState = Collections.unmodifiableMap(state);
        }

        return readonlyState;
    }

    public void validate() {
        model.validate(this);
    }
}